#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"QStack"
#include "cmath"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->lineEdit->setAlignment(Qt::AlignRight);
    ui->lineEdit->setText("0");
   //参数初始化
    operatorFlag = false;
    waittingForOperand=false;
    frontzero=true;

    //按键的绑定
        connect(ui->btn0, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn1, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn2, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn3, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn4, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn5, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn6, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn7, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn8, SIGNAL(clicked()), this, SLOT(btnnumClicked()));
        connect(ui->btn9, SIGNAL(clicked()), this, SLOT(btnnumClicked()));

       //符号（加减乘除和括号
        connect(ui->btnadd, SIGNAL(clicked()), this, SLOT(btnoprClicked()));
        connect(ui->btndiv, SIGNAL(clicked()), this, SLOT(btnoprClicked()));
        connect(ui->btnminus, SIGNAL(clicked()), this, SLOT(btnoprClicked()));
        connect(ui->btnmul, SIGNAL(clicked()), this, SLOT(btnoprClicked()));

        connect(ui->btnequ, SIGNAL(clicked()), this, SLOT(btnequClicked()));

}

MainWindow::~MainWindow()
{
    delete ui;

}
void MainWindow::btnnumClicked()//数字键显示和储存
{
    QPushButton *buttonClicked = qobject_cast<QPushButton *>(sender());
    int buttonValue = buttonClicked->text().toInt();
//    if(waittingForOperand)
//    {
//        ui->lineEdit->clear();
//        waittingForOperand = false;
//   }
    if(frontzero)
    {
          ui->lineEdit->clear();
          if(buttonValue)
          frontzero = false;
     }
    ui->lineEdit->setText(ui->lineEdit->text()+QString::number(buttonValue));
    operatorFlag=false;
}


void MainWindow::btnoprClicked()
{
    QPushButton *buttonClicked = qobject_cast<QPushButton *>(sender());
    if(!operatorFlag){
        QString op=buttonClicked->text();
        ui->lineEdit->setText(ui->lineEdit->text()+op);
        //waittingForOperand=true;
        operatorFlag=true;
        frontzero=false;
    }
    else return;
}

void MainWindow::on_btndel_clicked()
{

    QString text = ui->lineEdit->text();
   operatorFlag=false;
        text.chop(1);
        if(text.isEmpty())
        {
            text = "0";
            frontzero= true;
        }
        ui->lineEdit->setText(text);
        QString tar=text.right(1);
        if(tar<"0"||tar>"9")operatorFlag=true;
}



void MainWindow::btnequClicked(){

       //取框里内容，qstring转char*
        QString s2 = ui->lineEdit->text();
            QByteArray ba2;
            ba2.append(s2);     //也可以 ba2 = s2.toLatin1();
        char *src = ba2.data();
        double result=calculate(src);
        QString Result=QString::number(result,10,5);
       ui->lineEdit->setText(Result);

}

bool  MainWindow::IsPop(char a, char b)	//a为待比较符号，b为符号栈栈顶元素
{
    if (b == '(') return false;
    if (a == '*' || a == '/')
    {
        if (b == '+' || b == '-')
        {
            //可以入符号栈
            return false;
        }
        else
        {
            return true;
        }
    }
    //if (a == '+' || a == '-')
    //{
        //a符号为最低优先级，符号栈出栈
    return true;
    //}
}

/* 中缀转后缀 src带入中缀式，des带出后缀式 */
void MainWindow::InfixToSuffix(char* src, char* des)
{
    int k = 0;
    /* 符号栈 */
    QStack<char> symbol;

    int i = 0;

    while (src[i] != '\0')
    {

        if (src[i] == ' ')		//如果当前字符是空格，则往后走一个
        {
            i++;
            continue;
        }
        else if (src[i] >= '0' && src[i] <= '9')
        {
            des[k++] = src[i];
            if (src[i + 1] < '0' || src[i + 1]>'9')		//数字后加空格
            {
                des[k++] = ' ';
            }
        }
        else if (src[i] == '(')	//左括号直接入栈
        {
            symbol.push( src[i]);
        }
        else if (src[i] == ')')	//遇到 ） ，输出（ ）之间的所有符号
        {
            while (symbol.top()!= '(')
            {
                des[k++] = symbol.top();
                des[k++] = ' ';
                symbol.pop();
            }
            symbol.pop();
        }

        /*----------------- 运算符 -------------------------------*/
        else
        {
            switch (src[i])
            {
            case '+':case '-':case '*':case '/':
                if (symbol.empty())		//如果符号栈为空，直接入符号
                {
                    symbol.push(src[i]);
                }
                else				//否则，判断是否选择入符号栈还是出栈顶元素
                {
                    if (IsPop(src[i], symbol.top()))	//出符号栈
                    {
                        des[k++] = symbol.top();
                        des[k++] = ' ';
                        symbol.pop();
                        continue;
                    }
                    else			//当前符号优先级高，入符号栈
                    {
                        symbol.push(src[i]);
                    }
                }
                break;
            default:
                break;
            }

        }

        i++;	/* 遍历下一字符 */
    }
    /*字符串已遍历完，把符号栈中剩余的符号入栈到数字栈中 */
    while (!symbol.empty())
    {
        des[k++] = symbol.top();
        des[k++] = ' ';
        symbol.pop();
    }
    des[k] = '\0';
}
double MainWindow::calculate(char*src) {
    char* des = new char[3000];
    InfixToSuffix(src, des);
    QStack<double>num;
    int i = 0;
    while (des[i] != '\0') {
        while (des[i] >= '0' && des[i] <= '9' || des[i] == ' ') {
            if (des[i] != ' ')
            {
                QStack<double>temp ;
                                double tempnum=0;
                                temp.push(des[i] - '0');
                                int n = 1;
                                while (des[++i] != ' ') {
                                    temp.push(des[i]-'0');
                                }
                                while (!temp.empty()) {
                                    tempnum += temp.top() * n;
                                    n *= 10;
                                    temp.pop();
                                }
                                num.push(tempnum);
            }
            else i++;
        }
    while(des[i]< '0' || des[i]> '9' || des[i] == ' ')
    {
    double temp1 = 0, temp2 = 0, temp3 = 0;
    switch (des[i++]) {
    case'+':temp1 = num.top();
        num.pop();
        temp2 = num.top();
        num.pop();
        temp3 = temp1 + temp2;
        num.push(temp3);
        break;
    case'-': temp1 = num.top();
        num.pop();
        temp2 = num.top();
        num.pop();
        temp3 = temp2 - temp1;
        num.push(temp3);
        break;
    case'*':temp1 = num.top();
        num.pop();
        temp2 = num.top();
        num.pop();
        temp3 = temp2 * temp1;
        num.push(temp3);
        break;
    case'/': temp1 = num.top();
        num.pop();
        temp2 = num.top();
        num.pop();
        temp3 = temp2 / temp1;
        num.push(temp3);
        break;
    default:break;
    }
    if (des[i] == '\0')break;
    }
    }
    return num.top();
}
